home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / dvivga9.zip / OPENFONT.H < prev    next >
C/C++ Source or Header  |  1988-05-30  |  11KB  |  325 lines

  1. /* -*-C-*- openfont.h */
  2. /*-->openfont*/
  3. /**********************************************************************/
  4. /****************************** openfont ******************************/
  5. /**********************************************************************/
  6.  
  7. void
  8. openfont(fontname)
  9. char *fontname;
  10.  
  11. /***********************************************************************
  12.     The original version of this DVI driver reopened the font file  each
  13.     time the font changed, resulting in an enormous number of relatively
  14.     expensive file  openings.    This version  keeps  a cache  of  up  to
  15.     MAXOPEN open files,  so that when  a font change  is made, the  file
  16.     pointer, fontfp, can  usually be  updated from the  cache.  When the
  17.     file is not found in  the cache, it must  be opened.  In this  case,
  18.     the next empty slot  in the cache  is assigned, or  if the cache  is
  19.     full, the least used font file is closed and its slot reassigned for
  20.     the new file.  Identification of the least used file is based on the
  21.     counts of the number  of times each file  has been "opened" by  this
  22.     routine.  On return, the file pointer is always repositioned to  the
  23.     beginning of the file.
  24.  
  25.     If the first open attempt  fails, an attempt will  be made to use  a
  26.     substitute font, then neighboring magnifications (with the same font
  27.     name), or substitutes for them.
  28. ***********************************************************************/
  29.  
  30. {
  31.     register INT16 i,j,k;    /* loop indices */
  32.     INT16 current;
  33.     INT16 least_used;
  34.     INT16 maxopen = MAXOPEN;
  35.  
  36. #if    OS_VAXVMS
  37.     long *jpi;
  38. #endif
  39.  
  40.     struct font_entry *tfontptr;
  41.     char subfont[MAXFNAME];
  42.     int submag;
  43.     char* filelist[MAXFORMATS];    /* pointers to templist[][] */
  44.     char templist[MAXFORMATS][MAXFNAME];
  45.  
  46. #if    VIRTUAL_FONTS
  47.     struct stat statbuf;        /* so fstat() can get file size */
  48.     char *p;
  49. #endif
  50.  
  51.     if ((pfontptr != (struct font_entry *)NULL) && (pfontptr == fontptr))
  52.     return;            /* we need not have been called */
  53.  
  54.     for (j = 0; j < MAXFORMATS; ++j)    /* initialize fontlist pointers */
  55.     filelist[j] = &templist[j][0];
  56.  
  57. #if    IBM_PC_MICROSOFT
  58.     /* This code required rewriting to get around a fatal compiler
  59.     assertion error occasioned by the code in the #else part */
  60.     for (current = 1; current <= nopen; ++current)
  61.     {
  62.         FILE* pfp;
  63.  
  64.     pfp = font_files[current].font_id;
  65.     if (pfp == fontptr->font_file_id)
  66.         break;
  67.     }
  68. #else
  69.     for (current = 1;
  70.     (current <= nopen) &&
  71.         (font_files[current].font_id != fontptr->font_file_id);
  72.     ++current)
  73.     ;            /* try to find file in open list */
  74. #endif
  75.  
  76.     if (current <= nopen)    /* file already open, lookup its id */
  77.     fontfp = font_files[current].font_id;
  78.     else
  79.     {
  80.     /***************************************************************
  81.     The file was  not in list  of open  files.  If the  list is  not
  82.     full, add it to  the list; otherwise  close the least-used  file
  83.     and remove it from the font_entry containing it.  Finally,  open
  84.     the file, or its closest  neighbor in the magnification  family.
  85.     A warning is issued  if no file can  be opened.  The caller  can
  86.     then proceed with zero font metrics if desired.
  87.     ***************************************************************/
  88.  
  89. #if    OS_VAXVMS
  90.         /***************************************************************
  91.     VAX VMS has many user quotas, one of which is the maximum number
  92.     of files  that can be open, which  need have no relation  to the
  93.     number  that C  permits.  If  we do  not determine the  limit at
  94.     run-time, the drivers may attempt to open too many files, and in
  95.     such a case, will fail.   There  are two relevant  quotas, FILLM
  96.     (open file limit), and  FILCNT (remaining open file quota).   We
  97.     use the latter,  and leave  one available file  for a   possible
  98.     error log.
  99.     ***************************************************************/
  100.  
  101.     jpi = (long*)getjpi(JPI$_FILCNT);
  102.     if (jpi == (long*)NULL)
  103.         maxopen = MAXOPEN;        /* should never happen */
  104.     else
  105.         maxopen = nopen - 1 + *jpi;
  106.     maxopen = MIN(maxopen,MAXOPEN);    /* we have arrays of size MAXFONT */
  107.                     /* so do not exceed that limit */
  108. #endif /* OS_VAXVMS */
  109.  
  110.     if (nopen < maxopen)    /* just add it to list */
  111.         current = ++nopen;
  112.     else            /* list full -- find least used file, */
  113.     {            /* close it, and reuse slot for new file */
  114.         least_used = 1;
  115.         for (i = 2; i <= maxopen; ++i)
  116.         if (font_files[least_used].use_count >
  117.             font_files[i].use_count)
  118.             least_used = i;
  119.  
  120.         fontfp = font_files[least_used].font_id;
  121.         tfontptr = hfontptr;
  122.         while (tfontptr != (struct font_entry*)NULL)
  123.         {            /* remove file pointer from its font_entry */
  124.         if (tfontptr->font_file_id == fontfp)
  125.         {
  126.             tfontptr->font_file_id = (FILE*)NULL;
  127.             break;
  128.         }
  129.         tfontptr = tfontptr->next;
  130.         }
  131.  
  132. #if    VIRTUAL_FONTS
  133.         if (virt_font && (fontfp != (FILE*)NULL))
  134.             (void)virtfree(fontfp);
  135. #endif
  136.  
  137.         (void)fclose(fontfp);
  138.         fontfp = (FILE*)NULL;
  139.         current = least_used;
  140.     }
  141.     (void)actfact(fontptr->font_mag);    /* Get global mag_index */
  142.  
  143.     fontfp = (FILE*)NULL;
  144.  
  145.     /***************************************************************
  146.     Try the requested font, then any substitute font, then for  each
  147.     neighboring magnification  from  nearest to  furthest,  try  the
  148.     requested font, and then any substitute font.
  149.     ***************************************************************/
  150.  
  151.     for (k = 0; (fontfp == (FILE*)NULL) && (k < MAGTABSIZE); ++k)
  152.     {                /* loop over mag family */
  153.         for (i = -k; (fontfp == (FILE*)NULL) && (i <= k); i += MAX(1,k+k))
  154.         {                /* try smaller, then larger */
  155.         if (IN(0,mag_index+i,MAGTABSIZE-1))
  156.         {
  157.             (void)fontfile(filelist, ((fontptr->a==0)?fontpath:""),
  158.             fontname, (int)MAGSIZE(mag_table[mag_index+i]));
  159.             for (j = 0; (j < MAXFORMATS) && *filelist[j]; ++j)
  160.             {
  161.             fontfp = FOPEN(filelist[j],RB_OPEN);
  162.             DEBUG_OPEN(fontfp,filelist[j],RB_OPEN);
  163.             if (fontfp != (FILE *)NULL)
  164.             {
  165.                 strcpy(fontptr->name,filelist[j]);
  166.                 break;
  167.             }
  168.             }
  169.             if ((k > 0) && (fontfp != (FILE*)NULL))
  170.             {
  171.             (void)sprintf(message,
  172.                 "Font file [%s [mag %d]] could not be opened.\n\
  173. ---using nearest neighbor [%s [mag %d]] instead.",
  174.                 fontname,(int)MAGSIZE(mag_table[mag_index]),
  175.                 fontptr->name,
  176.                 (int)MAGSIZE(mag_table[mag_index+i]));
  177.             (void)warning(message);
  178.             }
  179.  
  180.             if ((fontfp == (FILE*)NULL) && fontsub(subfont,&submag,
  181.             fontname,(int)MAGSIZE(mag_table[mag_index+i])))
  182.             {
  183.             (void)fontfile(filelist,((fontptr->a==0)?fontpath:""),
  184.                 subfont,(submag ? submag :
  185.                 (int)MAGSIZE(mag_table[mag_index+i])));
  186.             for (j = 0; (j < MAXFORMATS) && *filelist[j]; ++j)
  187.             {
  188.                 fontfp = FOPEN(filelist[j],RB_OPEN);
  189.                 DEBUG_OPEN(fontfp,filelist[j],RB_OPEN);
  190.                 if (fontfp != (FILE *)NULL)
  191.                 {
  192.                 strcpy(fontptr->name,filelist[j]);
  193.                 break;
  194.                 }
  195.             }
  196.  
  197.             if (fontfp != (FILE*)NULL)
  198.             {
  199.                 (void)sprintf(message,
  200.                 "Substituting font file [%s [mag %d]] \
  201. by [%s [mag %d]]",
  202.                 fontname,(int)MAGSIZE(mag_table[mag_index]),
  203.                 fontptr->name,
  204.                 (int)MAGSIZE(mag_table[mag_index+i]));
  205.                 (void)warning(message);
  206.             }
  207.             }
  208.         }
  209.         } /* end for (i) -- loop over smaller and larger neighbors  */
  210.     } /* end for (k) -- loop over mag family */
  211.  
  212.     if (fontfp == (FILE*)NULL)
  213.     {
  214.         --nopen;            /* don't count this failed open */
  215.         (void)sprintf(message,"Font file [%s [mag %d]] could not be \
  216. opened; %d font files are open\n\
  217. Proceeding with zero size characters for this font",
  218.         fontname,(int)MAGSIZE(mag_table[mag_index]),nopen);
  219.         (void)warning(message);
  220.     }
  221.  
  222.     font_files[current].font_id = fontfp;
  223.     font_files[current].use_count = 0;
  224.  
  225. #if    VIRTUAL_FONTS
  226.     /*
  227.     ****************************************************************
  228.     This code  is implementation-dependent.   On many  C  compilers,
  229.     FILE points to a struct of the form
  230.  
  231.     struct    _iobuf {
  232.         char    *_ptr;    // pointer to next available char
  233.         int    _cnt;    // number